package cn.com.support.authentication;

import org.springframework.security.access.ConfigAttribute;

import cn.com.commons.code.AbstractCode;
import cn.com.commons.code.Code;

/**
 * 
 * 资源权限码，每个资源都有一个认证码和一个资源类型,在介绍资源认证码的时候必须先介绍一下系统用户认证码
 * <p>
 * 在系统进行资源认证的时候，会取出用户的认证码，用户认证码是一个资源类型和资源认证码的集合<br>
 * <strong>资源认证格式</strong>：menu：999,999&action:999,999<br>
 * &nbsp;&nbsp;&nbsp;&nbsp;通过<code>&</code>
 * 来区分用户拥有的资源访问类型，menu和action分别表示资源类型的名称，而后面的数值表示用户拥有的资源访问集合。它是多个64为的二进制的值的组合
 * <p>
 * 这里的ResourceAuthCode的code是一个数字，它表示每一个资源在用户认证码中所对应的位置，如果在用户认证码中找到了对应的位置，
 * 并且这个位置的值为1，则表示用户拥有此资源的权限。<p>
 * 
 * 如果要对用户资源访问进行认证可以使用{@link AuthenticationUtil}这个工具类
 * @since 2012-3-15 上午12:16:17
 * @version 1.0
 * @author Microbun
 * 
 */
public class ResourceAuthCode extends AbstractCode implements ConfigAttribute,Comparable {

	/**
	 * 表示为菜单类型的权限码
	 */
	public final static String TYPE_MENU = "menu";

	/**
	 * 表示为操作类型的权限码
	 */
	public final static String TYPE_ACTION = "action";

	private static final long serialVersionUID = -7180612549314538314L;

	/**
	 * 权限码的类型
	 */
	private String type;

	/**
	 * 构造一个权限码
	 * 
	 * @param code
	 */
	public ResourceAuthCode(String code) {
		this(code, null, null);
	}

	/**
	 * 构造一个权限码
	 * 
	 * @param code
	 * @param type
	 */
	public ResourceAuthCode(String code, String type) {
		this(code, type, null);
	}

	/**
	 * 构造一个权限码
	 * 
	 * @param code
	 * @param type
	 * @param description
	 */
	public ResourceAuthCode(String code, String type, String description) {
		super(code, description);
		this.type = type;
	}

	public String getType() {
		return type;
	}

	public void setType(String type) {
		this.type = type;
	}

	@Override
	public String getAttribute() {
		return code();
	}

	public boolean equals(Object obj) {
		if (obj instanceof ResourceAuthCode) {
			ResourceAuthCode authCode = (ResourceAuthCode) obj;
			return code.equals(authCode.code) && type.equals(authCode.type);
		}
		return false;
	}

	public int hashCode() {
		return (code + type).hashCode();
	}

	@Override
	public int compareTo(Object o) {
		return code().compareTo(((Code)o).code());
	}

}
